﻿// 10001 种树.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <stdio.h>

using namespace std;
/*
https://loj.ac/p/10001

题目描述
某条街被划为 n 条路段，这 n 条路段依次编号为 1~ n。
每个路段最多可以种一棵树。现在居民们给出了 h 组建议，每组建议包含三个整数 b,e,t，表示居民希望在路段 b 到 e 之间至少要种 t 棵树。
这些建议所给路段的区间可以交叉。请问：如果要满足所有居民的建议，至少要种多少棵树。

输入格式
第一行为 n，表示路段数。

第二行为 h，表示建议数。

下面 h 行描述一条建议：b, e, t，用一个空格分隔。

输出格式
输出只有一个数，为满足所有居民的建议，所需要种树的最少数量。

样例
输入
9
4
1 4 2
4 6 2
8 9 2
3 5 2

输出
5


数据范围与提示
100\% 的数据满足 0<n<= 3*10^4，h <= 5000，0<b <= e <= 3* 10^4，t <= e-b+1。
*/


const int N = 30010;
struct SEG {
	int l, r, tree;
}segs[N];
int n; int h;

int used[N];

bool cmp(const struct SEG& a, const struct SEG& b) {
	return a.r < b.r;
}


int main(){
 
	/*freopen("trees0.in", "r", stdin);
	freopen("out.txt", "w", stdout);*/

	//cin >> n >> h;
	scanf("%d%d",&n,&h);

	for (int i = 1; i <= h; i++) {
		scanf("%d%d%d",&(segs[i].l),&(segs[i].r),&(segs[i].tree));
		//cin >> segs[i].l >> segs[i].r >> segs[i].tree;
	}

	sort(segs+1,segs+1+h,cmp);

	int ans = 0;
	for (int i = 1; i <= h; i++) {
		//int l = segs[i].l; int r = segs[i].r; 
		int t = segs[i].tree;
		int haveused = 0;
		for (int j = segs[i].l; j <= segs[i].r; j++) {
			if(used[j])haveused++;
		}
		if (haveused < t) {
			
			int start = segs[i].r;
			while (t != haveused) {
				if (used[start] == 0) {
					used[start] =1; ans++;
					haveused++; start--;
				}
				else {
					start--;
				}
			}
			
			/*
			for (int j = segs[i].r; j >= segs[i].l; j--)//不满足，在结尾处加入
			{
				if (!used[j])
				{
					used[j] = 1;
					haveused++;
					ans++;//答案+1
					if (haveused == segs[i].tree) break;//满足退出
				}
			}
			*/
		}
	}
	
	//cout << ans << endl;
	printf("%d\n",ans);
	return 0;
}

 